'定制类'

# 枚举类
from enum import Enum, unique


class Student(object):
    def __init__(self, name) -> None:
        super().__init__()
        self.name = name

    # 直接打印类的时候，输出的结果(toString)
    def __str__(self) -> str:
        return 'student object'

    # 调试用的，和str一样
    def __repr__(self) -> str:
        return super().__repr__()

    # 获取属性的值，这里我做的一个判断
    # 虽然类里面没有score，但是如果要访问的话，默认输出60
    # 建议写上这个函数名，否则容易报错进行不下去
    # def __getattribute__(self, attr):
    #     if attr == 'score':
    #         return 60

    def __call__(self, *args, **kwds):
        print("My name is %s!" % self.name)


print(Student('zhangsan'))
s = Student('lisi')
# 这个是对应getattribute的
# print(s.score)

# 这个是对应call的（会和getattribute冲突）
s()


# 斐波那契数列对象
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1  # 初始化两个计数器a，b

    # __iter__函数，类似for循环
    def __iter__(self):
        # 实例本身就是迭代对象，故返回自己
        return self

    # 一直调用__next__方法，当出现StopIteration()报错时，停止调用
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        # 退出循环的条件
        if self.a > 100000:
            raise StopIteration()
            # 返回下一个值
        return self.a

    # 获取第i个对象（其实也要自己算的）
    def __getitem__(self, n):
        if isinstance(n, int):  # n是索引
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice):  # n是切片
            start = n.start
            stop = n.stop
            if start is None:
                start = 0
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L


# 输出斐波那契数列对象
for n in Fib():
    # print(n)
    pass

# 默认使用getitem方法，获取第5个对象
print(Fib()[5])

f = Fib()
f[0:5]  # 切片（相当于一个数列段）
f[:10]

# 枚举类
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
                       'Sep', 'Oct', 'Nov', 'Dec'))

# 这个members和items函数没有提示的，但是可以作为遍历使用
# for name, member in Month.__members__.items():
#     print(name, '=', member, member.value)


@unique
class WeekDay(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6


# 访问枚举类有很多方法，建议百度查看
print(WeekDay(1))
print(WeekDay.Mon.value)  # 等等方法

# 导入说明，from哪个文件，import哪个类
